#@TODO handle error 

import logging

try:
    from decorator import *
except:
    raise('Cant import decorator module. Pls install this module from http://www.phyast.pitt.edu/~micheles/python/documentation.html')


class Logger:
    funcLevel = -1
    spacer = ' '*4

    @classmethod
    def increment(self):
        self.funcLevel = self.funcLevel + 1

    @classmethod
    def decrement(self):
        self.funcLevel = self.funcLevel -1

    @classmethod
    def log(self,  logLevel, msg):
        logging.log(logLevel, self.funcLevel * self.spacer + msg)

    @classmethod
    def debug(self,  msg):
        self.log(logging.DEBUG,  msg)

    @classmethod
    def info(self,  msg):
        self.log(logging.INFO, msg)

    @classmethod
    def warning(self,  msg):
        self.log(logging.WARNING, msg)

    @classmethod
    def error(self,  msg):
        self.log(logging.ERROR,  msg)

    @classmethod
    def critical(self,  msg):
        self.log(logging.CRITICAL,  msg)




@decorator
def logged(f, *args, **kargs):
    fName = '['+ f.__name__ +'] - '
    Logger.increment()

    Logger.info(fName + 'Start')
    Logger.debug(fName + 'Input Params = ' + repr(args))

    try:
        try:
            returnValue = f(*args, **kargs)
            return returnValue
        except SystemExit:
            raise
        except Exception,  error:
            import pdb
            from sys import exc_info
            Logger.error('Caught Exception: ' +  repr(error))
            Logger.error(fName)
            pdb.post_mortem(exc_info()[2])
    finally:
        Logger.info(fName + 'End')
        Logger.decrement()

    return

if __name__ == '__main__':
    import logging
    
    @logged
    def subFunc():
        Logger.warning('Logging from subFunc')
        
    @logged
    def test():
        5/1 # valid statement
        Logger.info('write log msg as needed')
        subFunc()
        5/0 # invalid statement, will trigger pdb call in logged

    #logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s', filename='./myapp.log', filemode='w')
    logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
    test()

